package com.zyh.scs.admin.service.jd;

import com.alibaba.fastjson.JSON;
import com.zyh.scs.admin.api.bo.AutoLoginParam;
import com.zyh.scs.admin.api.bo.JDAuthDto;
import com.zyh.scs.admin.api.bo.JDAuthVo;
import com.zyh.scs.admin.api.constant.open.CodeSet;
import com.zyh.scs.admin.base.jd.ReturnURL;
import com.zyh.scs.admin.base.open.LaoSheResponse;
import com.zyh.scs.admin.utils.HeaderInfo;
import com.zyh.scs.admin.utils.HeaderUtil;
import com.zyh.scs.admin.utils.jd.AutologinParamUtil;
import com.zyh.scs.admin.utils.jd.SignatureUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class JDAuthServiceImpl implements JDAuthService {

    // @Autowired
    // QwDepartmentMapper qwDepartmentMapper;

    @Value("${biz.jd.bpin}")
    public String BPIN;

    @Value("${biz.jd.accessKey}")
    public String ACCESS_KEY;

    @Value("${biz.jd.rsaSignPrivateKey}")
    public String RSA_SIGN_PRIVATE_KEY;

    @Value("${biz.jd.rsaEncryptPublicKey}")
    public String RSA_ENCRYPT_PUBLIC_KEY;

    @Value("${biz.jd.authLoginUrl}")
    public String AUTH_LOGIN_URL;

    @Value("${biz.jd.returnUrl.home}")
    public String RETURN_URL_HOME;

    @Value("${biz.jd.returnUrl.goodsDetail}")
    public String RETURN_URL_GOODS_DETAIL;

    @Value("${biz.jd.returnUrl.shoppingCart}")
    public String RETURN_URL_SHOPPING_CART;

    @Value("${biz.jd.returnUrl.orderSubmit}")
    public String RETURN_URL_ORDER_SUBMIT;

    public static String replaceBlank(String str) {

        String dest = "";

        if (str != null) {

            Pattern p = Pattern.compile("\\s*|\t|\r|");
            Matcher m = p.matcher(str);

            dest = m.replaceAll("");
        }

        return dest;
    }

    /**
     * 授权登录
     *
     * @param dto
     * @param request
     * @return
     */
    @Override
    public LaoSheResponse<JDAuthVo> auth(JDAuthDto dto, HttpServletRequest request) {

        HeaderInfo headerInfo = HeaderUtil.getHeaderInfo(request);

        // ...

        return LaoSheResponse.error(CodeSet.SYSTEM_EXCEPTION, headerInfo.getTraceId());
    }

    /**
     * 授权登录-重定向
     *
     * @param dto
     * @param request
     * @param response
     * @return
     */
    @Override
    public void authRedirect(JDAuthDto dto, HttpServletRequest request, HttpServletResponse response) {

        String type = dto.getReturnType();
        String uid = dto.getUid();
        // 重定向地址
        String redirectUrl = AUTH_LOGIN_URL;
        // 登录成功后的重定向地址
        final ReturnURL returnURL = Arrays.stream(ReturnURL.values()).filter(r -> r.getCode().equals(type)).findAny().orElse(ReturnURL.HOME);
        String  returnUrl = switch (returnURL) {
            case HOME -> RETURN_URL_HOME;
            case DETAIL -> RETURN_URL_GOODS_DETAIL;
            case SHOPPING_CART -> RETURN_URL_SHOPPING_CART;
            case ORDER_SUBMIT -> RETURN_URL_ORDER_SUBMIT;
            default -> "";
        };


        AutoLoginParam autoLoginParam = null;

        try {
            autoLoginParam = AutologinParamUtil.getAutoLoginParam(RSA_SIGN_PRIVATE_KEY,
                    RSA_ENCRYPT_PUBLIC_KEY, ACCESS_KEY,
                    returnUrl, uid, "{}", "v1.0");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("授权登录-重定向 >>> 获取重定向入参数据异常 => ", e);
            return;
        }
        try {
            redirectUrl = this.print(autoLoginParam, redirectUrl);
        } catch (IllegalAccessException e) {
            // e.printStackTrace();
            log.error("授权登录-重定向 >>> 拼接重定向地址异常, autoLoginParam: {}", JSON.toJSONString(autoLoginParam), e);
            return;
        }

        log.info("授权登录-重定向 >>> 重定向地址: {}", redirectUrl);

        RedirectWithPost redirectWithPost = new RedirectWithPost(response);

        try {
            redirectWithPost.sendByPost(redirectUrl);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("授权登录-重定向 >>> 重定向异常, autoLoginParam: {}, redirectUrl: {}", JSON.toJSONString(autoLoginParam), redirectUrl, e);
        }
    }

    /**
     * 拼接url
     *
     * @param o
     * @param title
     * @return
     * @throws IllegalAccessException
     */
    private String print(Object o, String title) throws IllegalAccessException {

        if (o instanceof String) {
            return "";
        }

        TreeMap<String, Object> paramMap = SignatureUtil.objectToMap(o);
        StringBuilder sb = new StringBuilder();
        Iterator<Map.Entry<String, Object>> iterator1 = paramMap.entrySet().iterator();

        while (iterator1.hasNext()) {

            Map.Entry result1 = iterator1.next();

            if (result1.getValue() != null && !((String) result1.getValue()).trim().isEmpty()) {
                sb.append(result1.getKey() + "=" + replaceBlank(((String) result1.getValue()).trim()) + "&");
            }
        }

        String url = title + "&" + sb;
        url = url.replaceAll("\\+", "%2B");

        return url;
    }

    /**
     * 重定向 POST请求
     */
    public static class RedirectWithPost {

        Map<String, String> parameter = new HashMap<String, String>();
        HttpServletResponse response;

        public RedirectWithPost(HttpServletResponse response) {
            this.response = response;
        }

        public void setParameter(String key, String value) {
            this.parameter.put(key, value);
        }

        public void sendByPost(String url) throws IOException {

            this.response.setContentType("text/html");
            this.response.setCharacterEncoding("utf-8");
            this.response.setContentType("text/html;charset=utf-8");

            PrintWriter out = this.response.getWriter();

            out.println("<html>");
            out.println("<body>");
            out.println("<form name=\"commit\" action=\"" + url + "\" method=\"post\">");

            Iterator<String> it = this.parameter.keySet().iterator();

            while (it.hasNext()) {
                String key = it.next();
                out.println("<input type=\"hidden\" name=\"" + key + "\" value=\"" + this.parameter.get(key) + "\"/>");
            }

            out.println("</from>");
            out.println("<script>window.document.commit.submit();</script> ");
            out.println("</body>");
            out.println("</html>");

            out.flush();
            out.close();
        }
    }

}